# 请聊聊进程队列的特点和实现原理？
    # 特点 :
        # 1.进程之间的通信
        # 2.数据安全
        # 3.先进先出
    # 实现原理:
        # 基于管道 + 锁
        # 管道 基于文件级别的socket + pickle实现的
# 你了解生产者模型消费者模型么？如何实现？
    # 了解
    # 为什么了解? 工作经历
        # 采集图片/爬取音乐 :由于要爬取大量的数据,想提高爬取效率
        # 有用过一个生产者消费者模型,这个模型是我自己写的,消息中间件
        # 用的是xxx,获取网页的过程作为生产者,分析网页,获取所有歌曲链接
        # 作为消费者.
        # 自己写监控,或者是自己写邮件报警系统,监控程序作为生产者,一旦发现了
        # 有问题的程序就需要把这个需要发送的邮件信息交给消息中间件redis,
        # 消费者就从中间件中取值,然后来处理发邮件的逻辑.
    # 什么时候用过?
        # 项目 或者 例子
    # 在python中实现生产者消费者模型可以用哪些机制
        # 消息中间件
        # celery : 定时发短信的任务
# 从你的角度说说进程在计算机中扮演什么角色？
    # 资源分配的最小单位
    # 进程与进程之间内存隔离
    # 进程是由操作系统负责调度的,并且多个进程之间是一种竞争关系
    # 所以我们应该对进程的三状态时刻关注,尽量减少进程中的io操作,或者在进程里开线程来规避io
    # 让我们写的程序在运行的时候能够更多的占用cpu资源.
# 为什么线程之间数据不安全
    # 线程之间数据共享
    # 多线程的情况下,
        # 如果在计算某一个变量的时候,还要进行赋值操作,这个过程不是由一条完整的cpu指令完成的
        # 如果在判断某个bool表达式的之后,再做某些操作,这个过程也不是由一条完整的cpu指令完成的
        # 在中间发生了GIL锁的切换(时间片的轮转),可能会导致数据不安全.
# import threading
# import time
# loop = int(1E7)
# def _add(loop:int = 1):
#     global numbers
#     for _ in range(loop):
#         numbers.append(0)
# def _sub(loop:int = 1):
#     global number
#     for _ in range(loop):
#         while not numbers:
#             time.sleep(1E-8)
#         numbers.pop()
# numbers = [0]
# ta = threading.Thread(target=_add,args=(loop,))
# ts = threading.Thread(target=_sub,args=(loop,))
# ts2 = threading.Thread(target=_sub,args=(loop,))
# ta.start()
# ts.start()
# ta.join()
# ts.join()

# 内容回顾
# 守护线程
    # 守护线程会等待主线程(包括其他子线程)结束之后才结束
    # 守护线程的结束原理,主进程结束了,守护线程和其他所有线程资源一起被回收掉了
# 线程锁 - 最好只创建一把锁,线程锁一定锁不了进程
    # 互斥锁 : 在同一个进程中不能被连续acquire多次,一次acquire必须对应一次release
            #  相对效率高
    # 递归锁 :  在同一个进程中可以被连续acquire多次,但一次acquire必须对应一次release
    # 死锁现象 : 多把锁,交替使用(两把锁,在第一把锁没有释放之前就获取第二把锁)
        # locka.acquire()
        # lockb.acquire()
    # 怎么解决?
        # 最快的方法:把所有的互斥锁改成一把递归锁,影响效率
        # 后期再慢慢的整理逻辑,把递归锁能解决的问题用一把互斥锁解决掉,提高效率
    # 判断数据是否安全
        # 是否数据共享,是同步还是异步 (数据共享并且异步)
        # += -= *= /= 赋值 = 计算之后 数据不安全
        # if while 条件 这两个判断是由多个线程完成的 数据不安全
# 队列 queue
    # 线程队列
        # 数据安全
        # 先进先出
    # 原理 : 加锁 + 链表
        # 实现先进先出这件事 利用列表是不占优势的,效率低的
    # 先进先出的队列 Queue
    # 后进先出的队列 LIFOQueue 栈
    # 优先级队列 PriorityQueue 放入数据的ascii码来从小到大输出


